﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Web;
using System.Web.UI;
using Lswweb.Model;
using Lswweb.Common;

namespace Lswweb.Domain
{
    /// <summary>
    ///应用程序上下文
    ///Application_BeginRequest 时生成SiteContext并存于HttpContxt.Items中;
    /// </summary>
    public class SiteContext
    {
        #region 成员字段和构造方法

        private HttpContext context;

        private string currentUrl = string.Empty;
        private string currentOriginalUrl = string.Empty;
        private ReWrittenUrl reWrittenUrl = null;


        public SiteContext()
        {
            context = HttpContext.Current;

            if (context == null)
                return;

            reWrittenUrl = SiteUrls.GetRewriteUrl(context.Request.Path);
            if (reWrittenUrl != null)
                currentOriginalUrl = reWrittenUrl.Convert(context.Request.Path, context.Request.Url.Query);
        }

        #endregion

        #region Static 公共方法

        public static SiteContext Current
        {
            get
            {
                string currentItemKey = "siteContentKey";
                SiteContext siteContext = HttpContext.Current.Items[currentItemKey] as SiteContext;
                if (siteContext == null || HttpContext.Current == null)
                {
                    siteContext = new SiteContext();
                    HttpContext.Current.Items.Add(currentItemKey, siteContext);
                }
                return siteContext;
            }
        }

        /// <summary>
        /// Retrieves a value from the query string and returns it as an int.
        /// </summary>
        public static int GetIntFromQueryString(HttpContext context, string key)
        {
            string queryStringValue = GetFromQueryString(context, key);

            if (string.IsNullOrEmpty(queryStringValue))
                return -1;

            try
            {
                return Convert.ToInt32(queryStringValue);
            }
            catch (FormatException)
            {
                return -1;
            }
        }

        public static DateTime GetDateTimeFormQueryString(HttpContext context, string key)
        {
            string queryStringValue = GetFromQueryString(context, key);

            if (string.IsNullOrEmpty(queryStringValue))
                return DateTime.MinValue;

            try
            {
                return Convert.ToDateTime(queryStringValue);
            }
            catch (FormatException)
            {
                return DateTime.MinValue;
            }
        }

        public static bool? GetBooleanFromQueryString(HttpContext context, string key)
        {
            string queryStringValue = GetFromQueryString(context, key);

            if (string.IsNullOrEmpty(queryStringValue))
                return null;

            try
            {
                return RegexHelper.IsNumber(queryStringValue) ? Convert.ToBoolean(Convert.ToInt32(queryStringValue)) : Convert.ToBoolean(queryStringValue);
            }
            catch (FormatException)
            {
                return false;
            }
        }

        public static Pair<T> GetRangeFromQueryString<T>(HttpContext context, string key)
        {
            Pair<T> range=new Pair<T>(default(T), default(T));
            string queryStringValue = GetFromQueryString(context, key);

            if (!string.IsNullOrEmpty(queryStringValue))
            {
                try
                {
                    string[] rangeArgs = queryStringValue.Split('-');

                    T min = rangeArgs[0].As<T>();
                    T max = rangeArgs[1].As<T>();
                    range = new Pair<T>(min, max);
                }
                finally { }
            }

            return range;
        }

        public static string GetFromQueryString(HttpContext context, string key)
        {
            if (context == null
                || string.IsNullOrEmpty(key))
            {
                return string.Empty;
            }

            string queryValue = context.Request.QueryString[key];

            return queryValue == null ? string.Empty : queryValue;
        }

        /// <summary>
        /// 从网址中取得Url参数
        /// </summary>
        /// <returns></returns>
        public static string GetQueryStringByUrl(string queryKey, string url)
        {
            string queryString = string.Empty;
            Regex regex = new Regex("(^|[?&])" + queryKey + "=([^&]*)(&|$)");

            if (regex.IsMatch(url))
                queryString = regex.Match(url).Groups[2].Value;

            return queryString;
        }

        public static string GetApplicationName()
        {
            return GetApplicationName(HttpContext.Current);
        }

        public static string GetApplicationName(HttpContext context)
        {
            if (context == null)
                return "";

            string hostName = context.Request.Url.Host;
            string applicationPath = context.Request.ApplicationPath;

            return hostName + applicationPath;
        }

        /// <summary>
        /// 页面转向，无返回页则指向首页
        /// </summary>
        public static void Redirect()
        {
            Redirect(SiteUrls.Urls.Home);
        }
        /// <summary>
        /// 页面转向，无返回页则指向参数returnUrl的页面。
        /// </summary>
        /// <param name="returnUrl">指定返回的页面</param>
        public static void Redirect(string returnUrl)
        {
            string url = string.IsNullOrEmpty(returnUrl) ? Current.ReturnUrl : returnUrl;
            if (string.IsNullOrEmpty(url))
                Redirect();
            else
                Current.Context.Response.Redirect(url, true);
        }

        public static void RenderMessage(string title, string message, string redirectUrl)
        {
            Page page = SiteContext.Current.Context.Handler as Page;
            string redirectScript = string.IsNullOrEmpty(redirectUrl) ? string.Empty : "document.location.href='" + redirectUrl + "';";
            //注意如果修改这里的提示信息javascript代码，要注意符合common.js中ajaxHandler中的正则表达式。
            //page.ClientScript.RegisterStartupScript(typeof(Page), "alertMessage", "$(function(){$.blockUI({css:{padding:15},overlayCSS:{backgroundColor:'#fff',opacity:'0.4'} ,message:'<h4>操作提示</h4><p>" + message.Replace("\n", string.Empty).Replace("\r", string.Empty) + "</p><input id=\"closeAlertMessage\" type=button value=\"关闭\" />'});$(\"#closeAlertMessage\").click(function(){" + redirectScript + "$.unblockUI();});});", true);

            string faceBoxHtml=string.Format(
                "<div id=\"facebox\"><div class=\"close\"></div><h2>{0}</h2><div class=\"content\">{1}</div></div>",
                title,
                message);

            StringBuilder overlayBuilder = new StringBuilder();
            overlayBuilder.Append("$(function(){var faceBox = $('");
            overlayBuilder.Append(faceBoxHtml);
            overlayBuilder.Append("');");
            overlayBuilder.Append("$(document.body).append(faceBox);");
            overlayBuilder.Append("faceBox.overlay({ top: '30%', mask: { color: '#fff', loadSpeed: 200, opacity: 0.5 }, load: true , onClose:function(){");
            if (!string.IsNullOrEmpty(redirectUrl))
            {
                overlayBuilder.Append("document.location.href='");
                overlayBuilder.Append(redirectUrl);
                overlayBuilder.Append("';");
            }

            overlayBuilder.Append("}});");
            overlayBuilder.Append("setTimeout(function () {var api = $(\"#facebox\").data(\"overlay\");api.close();}, 2000);");
            overlayBuilder.Append("});");

            page.ClientScript.RegisterStartupScript(typeof(Page), "faceBox", overlayBuilder.ToString(), true);
        
        }
        public static void RenderMessage(ExceptionType exType)
        {
            RenderMessage(exType, Current.ReferrerUrl);
        }
        public static void RenderMessage(ExceptionType exType, string redirectUrl)
        {
            RenderMessage(exType, redirectUrl, null);
        }
        public static void RenderMessage(ExceptionType exType, string redirectUrl, params object[] args)
        {
            if (exType == ExceptionType.PageNotFond && string.IsNullOrEmpty(redirectUrl))
                redirectUrl = SiteUrls.Urls.Home;

            try
            {
                ExceptionMessage exMessage = ResourceManagement.Content.ExceptionMessages[exType];
                if (args != null)
                    RenderMessage(exMessage.Title, string.Format(exMessage.Body, args), redirectUrl);
                else
                    RenderMessage(exMessage.Title, exMessage.Body, redirectUrl);
            }
            catch
            {
                RenderMessage(exType.ToString(), exType.ToString(), redirectUrl);
            }
        }


        #endregion

        #region Public Properties

        #region Url Query

        public string SearchKey
        {
            get { return GetFromQueryString(context, "SearchKey"); }
        }

        public int SearchType
        {
            get { return GetIntFromQueryString(context, "SearchType"); }
        }

        public int Status
        {
            get { return GetIntFromQueryString(context, "Status"); }
        }

        public int AuditingStatus
        {
            get { return GetIntFromQueryString(context, "AuditingStatus"); }
        }

        public bool? IsTrue
        {
            get { return GetBooleanFromQueryString(context, "IsTrue"); }
        }

        public int Type
        {
            get { return GetIntFromQueryString(context, "Type"); }
        }

        public DateTime MinDateTime
        {
            get { return GetDateTimeFormQueryString(context, "MinDateTime"); }
        }

        public DateTime MaxDateTime
        {
            get { return GetDateTimeFormQueryString(context, "MaxDateTime"); }
        }

        public int CategoryId
        {
            get { return GetIntFromQueryString(context, "CategoryId"); }
        }

        public int BaseNodeId
        {
            get { return GetIntFromQueryString(context, "BaseNodeId"); }
        }

        public Pair<Decimal?> DecimalRange
        {
            get { return GetRangeFromQueryString<Decimal?>(context, "DecimalRange"); }
        }

        public int Id
        {
            get { return GetIntFromQueryString(context, "Id"); }
        }

        public string Parameters
        {
            get { return GetFromQueryString(context, "Parameters"); }
        }

        public bool EnableDelButton
        {
            get 
            { 
                var result=GetBooleanFromQueryString(context, "EnableDelBtn");
                if (result == null)
                    return false;

                return result.Value;
            }
        }

        public bool EnableTopButton
        {
            get 
            { 
                var result=GetBooleanFromQueryString(context, "EnableTopBtn");
                if (result == null)
                    return false;

                return result.Value;
            }
        }

        public bool EnableHotButton
        {
            get 
            { 
                var result=GetBooleanFromQueryString(context, "EnableHotBtn");
                if (result == null)
                    return false;

                return result.Value;
            }
        }

        public string FileName
        {
            get { return GetFromQueryString(context, "FileName"); }
        }

        public string ReturnUrl
        {
            get { return GetFromQueryString(context, "ReturnUrl"); }
        }

        #endregion

        #region 页面Url信息

        public ReWrittenUrl ReWrittenUrl
        {
            get { return reWrittenUrl; }
        }

        /// <summary>
        /// 重写前的原始Url
        /// </summary>
        public string CurrentOriginalUrl
        {
            get { return currentOriginalUrl; }
        }

        /// <summary>
        /// 当前Url
        /// </summary>
        public string CurrentUrl
        {
            get
            {
                if (string.IsNullOrEmpty(currentUrl))
                    currentUrl = context.Request.RawUrl;
                return currentUrl;
            }
        }

        /// <summary>
        /// 上次请求的Url
        /// </summary>
        public string ReferrerUrl
        {
            get
            {
                if (context.Request.UrlReferrer != null)
                    return context.Request.UrlReferrer.PathAndQuery;
                else
                    return SiteUrls.Urls.Home;
            }
        }

        #endregion

        public HttpContext Context
        {
            get
            {
                if (context == null)
                    return new HttpContext(null);

                return context;
            }
        }

        public UserInfo User
        {
            get { return Users.GetUser(this.UserName); }
        }

        public string UserName
        {
            get
            {
                if (Context.User.Identity.IsAuthenticated)
                    return Context.User.Identity.Name;
                else
                    return string.Empty;
            }
        }

        private MapNode mapNode;
        public MapNode MapNode
        {
            get
            {
                if (mapNode == null)
                    mapNode = Maps.Content.CurrentUrlNode();
                return mapNode;
            }
        }

        public string IpAddress
        {
            get
            {
                string result = String.Empty;

                result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (string.IsNullOrEmpty(result))
                {
                    result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                if (string.IsNullOrEmpty(result))
                {
                    result = HttpContext.Current.Request.UserHostAddress;
                }

                if (string.IsNullOrEmpty(result))
                {
                    return "127.0.0.1";
                }

                return result;
            }
        }

        private string _language = string.Empty;
        public string Language
        {
            get
            {
                if (string.IsNullOrEmpty(_language))
                {
                    HttpCookie obj = HttpContext.Current.Request.Cookies["mx9_language"];
                    if (obj == null)
                        _language = "zh-cn";
                    else
                        _language = obj.Value;
                }
                return _language;
            }
            set
            {
                if (value != _language)
                {
                    HttpCookie cookie = new HttpCookie("mx9_language", value);
                    HttpContext.Current.Response.Cookies.Add(cookie);
                }
            }
        }

        public Currency CurrentCurrency
        {
            get
            {
                Currency currency = this.context.Session == null
                    ? null
                    : this.context.Session["currentCurrency"] as Currency;

                if (currency == null)
                    currency = CurrencyServices.GetDefaultCurrency();

                return currency;
            }
            set
            {
                Currency currency = this.context.Session["currentCurrency"] as Currency;
                if (currency == null)
                {
                    this.context.Session.Add("currentCurrency", value);
                }
                else
                {
                    this.context.Session["currentCurrency"] = value;
                }
            }
        }

        #endregion
    }
}
